package marchingCubes;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Vector;

import processing.core.PGraphics;


public class CopyOfCAADMCube {
	public float[] xc;
	public float[] yc;
	public float[] zc;
	public int[]triangles;
	public int[]trianglesData;
	public void loadOBJ(String file) {
	DataInputStream in = null;
	BufferedReader br = null;
	try {
		FileInputStream fstream = new FileInputStream(file);
		in = new DataInputStream(fstream);
		br = new BufferedReader(new InputStreamReader(in));
		String strLine;
		try {
			int nV=0;
			int nF=0;
			// finding the length;
			strLine = br.readLine();
			while (strLine != null) {
				int comment=0;
				if (strLine.startsWith("v ")) {
					nV++;
				}
				else if (strLine.startsWith("f ")){
					nF++;
				}
				strLine = br.readLine();
			}
			// init arrays
			xc=new float[nV];
			yc=new float[nV];
			zc=new float[nV];
			triangles=new int[nF];
			
			// loading the data;
			br = new BufferedReader(new InputStreamReader(in));
			int iV=0;
			int iF=0;
			strLine = br.readLine();
			while (strLine != null) {
				if (strLine.startsWith("v ")) {
					String[] data = strLine.split(" ");
					xc[iV]= Float.valueOf(data[1]);
					yc[iV]= Float.valueOf(data[2]);
					zc[iV]= Float.valueOf(data[3]);
					iV++;
				}
				else if (strLine.startsWith("f ")){
					String[] data = strLine.split(" ");
					for (int i = 1; i < 4; i++) {
						String[]number=data[i].split("/");
						triangles[iF]=Integer.valueOf(number[0])-1;
						iF++;
					}
				}
				strLine = br.readLine();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	} catch (Exception e) {// Catch exception if any
		System.err.println("Error: " + e.getMessage());
	}
}

public void saveObj(String file){
	FileWriter fw;
	try {
		fw = new FileWriter(file);
		BufferedWriter bw = new BufferedWriter(fw);
		for (int i = 0; i <this.xc.length; i++) {
			bw.write("v "+xc[i]+" "+ yc[i]+" "+ zc[i]);
			bw.newLine();
		}
		for (int i = 0; i <triangles.length; i+=3) {
			bw.write("f " +(triangles[i]+1)+" "+(triangles[i+1]+1) +" "+(triangles[i+2]+1));
			bw.newLine();
		}
		bw.flush();
		bw.close();
		System.out.println("OBJ exported: "+file);
	} catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
}
public void saveObjGroup(String file){
	FileWriter fw;
	try {
		fw = new FileWriter(file);
		BufferedWriter bw = new BufferedWriter(fw);
		for (int i = 0; i <this.xc.length; i++) {
			bw.write("v "+xc[i]+" "+ yc[i]+" "+ zc[i]);
			bw.newLine();
		}
		int indexGroup=0;
		for (int i = 0; i <triangles.length; i+=3) {
			bw.write("g " +trianglesData[indexGroup]);
			bw.newLine();
			bw.write("f " +(triangles[i]+1)+" "+(triangles[i+1]+1) +" "+(triangles[i+2]+1));
			bw.newLine();
			indexGroup++;
		}
		bw.flush();
		bw.close();
		System.out.println("OBJ exported: "+file);
	} catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
}

public void draw(PGraphics g3d){
	g3d.beginShape(PGraphics.TRIANGLES);
	for (int i = 0; i <triangles.length; i++) {
		g3d.vertex(xc[triangles[i]],yc[triangles[i]],zc[triangles[i]]);
	}
	g3d.endShape();
}


// marching cubes, data can be null or nx*ny*nz int array
public  void marchingCubes(int nX,int nY,int nZ,float[] values,int[]data,
		float iso) {

	int nYZ=nY*nZ;
	int nXYZ=nX*nY*nZ;
	int nVs=0;
	int index=0;

	for (int x=0;x<nX;x++){
		for (int y=0;y<nY;y++){
			for (int z=0;z<nZ;z++){
				float cV=values[index];
				if (x<nX-1){
					float xNb=values[index+nYZ];
					if (cV<iso!=xNb<iso){
						nVs++;
					}
				}
				if (y<nY-1){
					float yNb=values[index+nZ];
					if (cV<iso!=yNb<iso){
						nVs++;
					}
				}
				if (z<nZ-1){
					float zNb=values[index+1];
					if (cV<iso!=zNb<iso){
						nVs++;
					}
				}
				index++;
			}
		}
	}
	xc=new float[nVs];
	yc=new float[nVs];
	zc=new float[nVs];
	int[]xE=new int[nXYZ];
	int[]yE=new int[nXYZ];
	int[]zE=new int[nXYZ];
	nVs=0;
	index=0;
	
	for (int x=0;x<nX;x++){
		for (int y=0;y<nY;y++){
			for (int z=0;z<nZ;z++){
				float cV=values[index];
				if (x<nX-1){
					float xNb=values[index+nYZ];
					if (cV<iso!=xNb<iso){
						xc[nVs]=getValue(iso,cV,xNb)+x;
						yc[nVs]=y;
						zc[nVs]=z;
						xE[index]=nVs;
						nVs++;
					}
				}
				if (y<nY-1){
					float yNb=values[index+nZ];
					if (cV<iso!=yNb<iso){
						xc[nVs]=x;
						yc[nVs]=getValue(iso,cV,yNb)+y;
						zc[nVs]=z;
						yE[index]=nVs;
						nVs++;
					}
				}
				if (z<nZ-1){
					float zNb=values[index+1];
					if (cV<iso!=zNb<iso){
						xc[nVs]=x;
						yc[nVs]=y;
						zc[nVs]=getValue(iso,cV,zNb)+z;
						zE[index]=nVs;
						nVs++;
					}
				}
				index++;
			}
		}
	}
	
	ArrayList<int[]>triangleList=new ArrayList<int[]>();
	float[]nbs=new float[8];
	int[]edges=new int[12];
	
	index=0;
	for (int x = 0; x < nX; x++) {
		for (int y = 0; y < nY; y++) {
			for (int z = 0; z < nZ; z++) {
				if (x < nX - 1 && y < nY - 1 && z < nZ - 1) {
					int caseNumber = 0;
					
					nbs[0] = values[index + nZ];
					nbs[1] = values[index + nYZ + nZ];
					nbs[2] = values[index + nYZ];
					nbs[3] = values[index];
					nbs[4] = values[index + nZ + 1];
					nbs[5] = values[index + nYZ + nZ + 1];
					nbs[6] = values[index + nYZ + 1];
					nbs[7] = values[index + 1];

					for (int i = 7; i > -1; i--) {
						if (nbs[i] > iso) {
							caseNumber++;
						}
						if (i > 0) {
							caseNumber = caseNumber << 1;
						}
					}

					edges[0] = xE[index + nZ];
					edges[1] = yE[index + nYZ];
					edges[2] = xE[index];
					edges[3] = yE[index];
					edges[4] = xE[index + nZ + 1];
					edges[5] = yE[index + nYZ + 1];
					edges[6] = xE[index + 1];
					edges[7] = yE[index + 1];
					edges[8] = zE[index + nZ];
					edges[9] = zE[index + nYZ + nZ];
					edges[10] =zE[index ];
					edges[11] =zE[index + nYZ];
					
					
					int offset = caseNumber * 15;
					if (data==null){
					for (int i = offset; i < offset + 15; i += 3) {
						if (faces[i] > -1) {
							int v0 = edges[faces[i]];
							int v1 = edges[faces[i + 1]];
							int v2 = edges[faces[i + 2]];
							int[] triangle = new int[] { v0, v1, v2 };
							triangleList.add(triangle);
						}
					}
					}
					else{
						for (int i = offset; i < offset + 15; i += 3) {
							if (faces[i] > -1) {
								int v0 = edges[faces[i]];
								int v1 = edges[faces[i + 1]];
								int v2 = edges[faces[i + 2]];
								int[] triangle = new int[] { v0, v1, v2,data[index] };
								triangleList.add(triangle);
							}
						}
					}
				}
				index++;
			}
		}
	}
	
	triangles=new int[triangleList.size()*3];
	for (int i=0;i<triangleList.size();i++){
		int[]triangle=triangleList.get(i);
		int cIndex=i*3;
		for (int j=0;j<3;j++){
			triangles[cIndex+j]=triangle[j];
		}
	}
	
	if (data!=null){
		trianglesData=new int[triangleList.size()];
		for (int i=0;i<triangleList.size();i++){
			int[]triangle=triangleList.get(i);
			trianglesData[i]=triangle[3];
		}
	}
}


	// marching cubes, data can be null or nx*ny*nz int array
	// values need to be created in x y z order
	public void marchingCubesMinim(int nX, int nY, int nZ, float[] values,
			float iso) {
		int nYZ = nY * nZ;
		int nVs = 0;
		int index = 0;
		ArrayList<int[]> triangleList = new ArrayList<int[]>();
		ArrayList<float[]> vertices = new ArrayList<float[]>();
		float[] nbs = new float[8];
		int[] edges = new int[12];
		int[][] xEdges = new int[nX][nZ];
		int[][] yEdges = new int[nX][nZ];
		int[][] xEdgesUp = new int[nX][nZ];
		int[][] yEdgesUp = new int[nX][nZ];
		int[][] zEdges = new int[nX][nZ];
		for (int y = 0; y < nY - 1; y++) {
			// collecting the Vertices and Edges
			copyValuesFromAToB(yEdgesUp, yEdges);
			copyValuesFromAToB(xEdgesUp, xEdges);
			for (int x = 0; x < nX-1; x++) {
				for (int z = 0; z < nZ-1; z++) {
					index=z+y*nZ+x*nYZ;
					float cV = values[index];
					float xNb = values[index + nYZ];
					if (cV < iso != xNb < iso) {
						vertices.add(new float[] { getValue(iso, cV, xNb) + x,
								y, z });
						xEdgesUp[x][z] = nVs;
						nVs++;
					}
					float yNb = values[index + nZ];
					if (cV < iso != yNb < iso) {
						vertices.add(new float[] { x,
								getValue(iso, cV, yNb) + y, z });
						yEdgesUp[x][z] = nVs;
						nVs++;
					}
					float zNb = values[index + 1];
					if (cV < iso != zNb < iso) {
						vertices.add(new float[] { x, y,
								getValue(iso, cV, zNb) + z });
						zEdges[x][z] = nVs;
						nVs++;
					}
				}
			}
			// collecting the faces
			for (int x = 0; x < nX - 1; x++) {
				for (int z = 0; z < nZ - 1; z++) {
					int caseNumber = 0;
					index=z+y*nZ+x*nYZ;
					nbs[0] = values[index + nZ];
					nbs[1] = values[index + nYZ + nZ];
					nbs[2] = values[index + nYZ];
					nbs[3] = values[index];
					nbs[4] = values[index + nZ + 1];
					nbs[5] = values[index + nYZ + nZ + 1];
					nbs[6] = values[index + nYZ + 1];
					nbs[7] = values[index + 1];
					for (int i = 7; i > -1; i--) {
						if (nbs[i] > iso) {
							caseNumber++;
						}
						if (i > 0) {
							caseNumber = caseNumber << 1;
						}
					}
					edges[0] = xEdges[x][z + 1];
					edges[1] = yEdges[x + 1][z];
					edges[2] = xEdges[x][z];
					edges[3] = yEdges[x][z];
					edges[4] = xEdgesUp[x][z + 1];
					edges[5] = yEdgesUp[x + 1][z];
					edges[6] = xEdgesUp[x][z];
					edges[7] = yEdgesUp[x][z];
					edges[8] = zEdges[x][z + 1];
					edges[9] = zEdges[x + 1][z + 1];
					edges[10] = zEdges[x][z];
					edges[11] = zEdges[x + 1][z];
					int offset = caseNumber * 15;
					for (int i = offset; i < offset + 15; i += 3) {
						if (faces[i] > -1) {
							int v0 = edges[faces[i]];
							int v1 = edges[faces[i + 1]];
							int v2 = edges[faces[i + 2]];
							int[] triangle = new int[] { v0, v1, v2 };
							triangleList.add(triangle);
						}
					}

				}
			}
		}
		triangles = new int[triangleList.size() * 3];
		for (int i = 0; i < triangleList.size(); i++) {
			int[] triangle = triangleList.get(i);
			int cIndex = i * 3;
			for (int j = 0; j < 3; j++) {
				triangles[cIndex + j] = triangle[j];
			}
		}
		xc=new float[vertices.size()];
		yc=new float[vertices.size()];
		zc=new float[vertices.size()];
		for (int i=0;i<vertices.size();i++){
			float[] v=vertices.get(i);
			xc[i]=v[0];
			yc[i]=v[1];
			zc[i]=v[2];
		}
	}
public void copyValuesFromAToB(int[][] array1,int[][] array2){
	for (int i=0;i<array1.length;i++){
		for (int j=0;j<array1[0].length;j++){
			array2[i][j]=array1[i][j];
		}
	}
}

public  float getValue(float iso, float v1,float v2){
	if (Math.abs(v2-v1)<0.0001f)return 0;
	return (iso-v1)/(v2-v1);
}

private static int faces[] =
{
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 8, 3, 1, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    9, 2, 11, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    2, 8, 3, 2, 11, 8, 11, 9, 8, -1, -1, -1, -1, -1, -1,
    3, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 10, 2, 8, 10, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1, 9, 0, 2, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1, 10, 2, 1, 9, 10, 9, 8, 10, -1, -1, -1, -1, -1, -1,
    3, 11, 1, 10, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 11, 1, 0, 8, 11, 8, 10, 11, -1, -1, -1, -1, -1, -1,
    3, 9, 0, 3, 10, 9, 10, 11, 9, -1, -1, -1, -1, -1, -1,
    9, 8, 11, 11, 8, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1,
    1, 2, 11, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    3, 4, 7, 3, 0, 4, 1, 2, 11, -1, -1, -1, -1, -1, -1,
    9, 2, 11, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1,
    2, 11, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1,
    8, 4, 7, 3, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    10, 4, 7, 10, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1,
    9, 0, 1, 8, 4, 7, 2, 3, 10, -1, -1, -1, -1, -1, -1,
    4, 7, 10, 9, 4, 10, 9, 10, 2, 9, 2, 1, -1, -1, -1,
    3, 11, 1, 3, 10, 11, 7, 8, 4, -1, -1, -1, -1, -1, -1,
    1, 10, 11, 1, 4, 10, 1, 0, 4, 7, 10, 4, -1, -1, -1,
    4, 7, 8, 9, 0, 10, 9, 10, 11, 10, 0, 3, -1, -1, -1,
    4, 7, 10, 4, 10, 9, 9, 10, 11, -1, -1, -1, -1, -1, -1,
    9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1,
    1, 2, 11, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    3, 0, 8, 1, 2, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1,
    5, 2, 11, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1,
    2, 11, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1,
    9, 5, 4, 2, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 10, 2, 0, 8, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1,
    0, 5, 4, 0, 1, 5, 2, 3, 10, -1, -1, -1, -1, -1, -1,
    2, 1, 5, 2, 5, 8, 2, 8, 10, 4, 8, 5, -1, -1, -1,
    11, 3, 10, 11, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1,
    4, 9, 5, 0, 8, 1, 8, 11, 1, 8, 10, 11, -1, -1, -1,
    5, 4, 0, 5, 0, 10, 5, 10, 11, 10, 0, 3, -1, -1, -1,
    5, 4, 8, 5, 8, 11, 11, 8, 10, -1, -1, -1, -1, -1, -1,
    9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1,
    0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1,
    1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    9, 7, 8, 9, 5, 7, 11, 1, 2, -1, -1, -1, -1, -1, -1,
    11, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1,
    8, 0, 2, 8, 2, 5, 8, 5, 7, 11, 5, 2, -1, -1, -1,
    2, 11, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1,
    7, 9, 5, 7, 8, 9, 3, 10, 2, -1, -1, -1, -1, -1, -1,
    9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 10, -1, -1, -1,
    2, 3, 10, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1,
    10, 2, 1, 10, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1,
    9, 5, 8, 8, 5, 7, 11, 1, 3, 11, 3, 10, -1, -1, -1,
    5, 7, 0, 5, 0, 9, 7, 10, 0, 1, 0, 11, 10, 11, 0,
    10, 11, 0, 10, 0, 3, 11, 5, 0, 8, 0, 7, 5, 7, 0,
    10, 11, 5, 7, 10, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    11, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 8, 3, 5, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    9, 0, 1, 5, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1, 8, 3, 1, 9, 8, 5, 11, 6, -1, -1, -1, -1, -1, -1,
    1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1,
    9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1,
    5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1,
    2, 3, 10, 11, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    10, 0, 8, 10, 2, 0, 11, 6, 5, -1, -1, -1, -1, -1, -1,
    0, 1, 9, 2, 3, 10, 5, 11, 6, -1, -1, -1, -1, -1, -1,
    5, 11, 6, 1, 9, 2, 9, 10, 2, 9, 8, 10, -1, -1, -1,
    6, 3, 10, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1,
    0, 8, 10, 0, 10, 5, 0, 5, 1, 5, 10, 6, -1, -1, -1,
    3, 10, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1,
    6, 5, 9, 6, 9, 10, 10, 9, 8, -1, -1, -1, -1, -1, -1,
    5, 11, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4, 3, 0, 4, 7, 3, 6, 5, 11, -1, -1, -1, -1, -1, -1,
    1, 9, 0, 5, 11, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1,
    11, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1,
    6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1,
    1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1,
    8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1,
    7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9,
    3, 10, 2, 7, 8, 4, 11, 6, 5, -1, -1, -1, -1, -1, -1,
    5, 11, 6, 4, 7, 2, 4, 2, 0, 2, 7, 10, -1, -1, -1,
    0, 1, 9, 4, 7, 8, 2, 3, 10, 5, 11, 6, -1, -1, -1,
    9, 2, 1, 9, 10, 2, 9, 4, 10, 7, 10, 4, 5, 11, 6,
    8, 4, 7, 3, 10, 5, 3, 5, 1, 5, 10, 6, -1, -1, -1,
    5, 1, 10, 5, 10, 6, 1, 0, 10, 7, 10, 4, 0, 4, 10,
    0, 5, 9, 0, 6, 5, 0, 3, 6, 10, 6, 3, 8, 4, 7,
    6, 5, 9, 6, 9, 10, 4, 7, 9, 7, 10, 9, -1, -1, -1,
    11, 4, 9, 6, 4, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4, 11, 6, 4, 9, 11, 0, 8, 3, -1, -1, -1, -1, -1, -1,
    11, 0, 1, 11, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1,
    8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 11, -1, -1, -1,
    1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1,
    3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1,
    0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1,
    11, 4, 9, 11, 6, 4, 10, 2, 3, -1, -1, -1, -1, -1, -1,
    0, 8, 2, 2, 8, 10, 4, 9, 11, 4, 11, 6, -1, -1, -1,
    3, 10, 2, 0, 1, 6, 0, 6, 4, 6, 1, 11, -1, -1, -1,
    6, 4, 1, 6, 1, 11, 4, 8, 1, 2, 1, 10, 8, 10, 1,
    9, 6, 4, 9, 3, 6, 9, 1, 3, 10, 6, 3, -1, -1, -1,
    8, 10, 1, 8, 1, 0, 10, 6, 1, 9, 1, 4, 6, 4, 1,
    3, 10, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1,
    6, 4, 8, 10, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    7, 11, 6, 7, 8, 11, 8, 9, 11, -1, -1, -1, -1, -1, -1,
    0, 7, 3, 0, 11, 7, 0, 9, 11, 6, 7, 11, -1, -1, -1,
    11, 6, 7, 1, 11, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1,
    11, 6, 7, 11, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1,
    1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1,
    2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9,
    7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1,
    7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    2, 3, 10, 11, 6, 8, 11, 8, 9, 8, 6, 7, -1, -1, -1,
    2, 0, 7, 2, 7, 10, 0, 9, 7, 6, 7, 11, 9, 11, 7,
    1, 8, 0, 1, 7, 8, 1, 11, 7, 6, 7, 11, 2, 3, 10,
    10, 2, 1, 10, 1, 7, 11, 6, 1, 6, 7, 1, -1, -1, -1,
    8, 9, 6, 8, 6, 7, 9, 1, 6, 10, 6, 3, 1, 3, 6,
    0, 9, 1, 10, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    7, 8, 0, 7, 0, 6, 3, 10, 0, 10, 6, 0, -1, -1, -1,
    7, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    7, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    3, 0, 8, 10, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 1, 9, 10, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    8, 1, 9, 8, 3, 1, 10, 7, 6, -1, -1, -1, -1, -1, -1,
    11, 1, 2, 6, 10, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1, 2, 11, 3, 0, 8, 6, 10, 7, -1, -1, -1, -1, -1, -1,
    2, 9, 0, 2, 11, 9, 6, 10, 7, -1, -1, -1, -1, -1, -1,
    6, 10, 7, 2, 11, 3, 11, 8, 3, 11, 9, 8, -1, -1, -1,
    7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1,
    2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1,
    1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1,
    11, 7, 6, 11, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1,
    11, 7, 6, 1, 7, 11, 1, 8, 7, 1, 0, 8, -1, -1, -1,
    0, 3, 7, 0, 7, 11, 0, 11, 9, 6, 11, 7, -1, -1, -1,
    7, 6, 11, 7, 11, 8, 8, 11, 9, -1, -1, -1, -1, -1, -1,
    6, 8, 4, 10, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    3, 6, 10, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1,
    8, 6, 10, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1,
    9, 4, 6, 9, 6, 3, 9, 3, 1, 10, 3, 6, -1, -1, -1,
    6, 8, 4, 6, 10, 8, 2, 11, 1, -1, -1, -1, -1, -1, -1,
    1, 2, 11, 3, 0, 10, 0, 6, 10, 0, 4, 6, -1, -1, -1,
    4, 10, 8, 4, 6, 10, 0, 2, 9, 2, 11, 9, -1, -1, -1,
    11, 9, 3, 11, 3, 2, 9, 4, 3, 10, 3, 6, 4, 6, 3,
    8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1,
    0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1,
    1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1,
    8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 11, 1, -1, -1, -1,
    11, 1, 0, 11, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1,
    4, 6, 3, 4, 3, 8, 6, 11, 3, 0, 3, 9, 11, 9, 3,
    11, 9, 4, 6, 11, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4, 9, 5, 7, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 8, 3, 4, 9, 5, 10, 7, 6, -1, -1, -1, -1, -1, -1,
    5, 0, 1, 5, 4, 0, 7, 6, 10, -1, -1, -1, -1, -1, -1,
    10, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1,
    9, 5, 4, 11, 1, 2, 7, 6, 10, -1, -1, -1, -1, -1, -1,
    6, 10, 7, 1, 2, 11, 0, 8, 3, 4, 9, 5, -1, -1, -1,
    7, 6, 10, 5, 4, 11, 4, 2, 11, 4, 0, 2, -1, -1, -1,
    3, 4, 8, 3, 5, 4, 3, 2, 5, 11, 5, 2, 10, 7, 6,
    7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1,
    9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1,
    3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1,
    6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8,
    9, 5, 4, 11, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1,
    1, 6, 11, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4,
    4, 0, 11, 4, 11, 5, 0, 3, 11, 6, 11, 7, 3, 7, 11,
    7, 6, 11, 7, 11, 8, 5, 4, 11, 4, 8, 11, -1, -1, -1,
    6, 9, 5, 6, 10, 9, 10, 8, 9, -1, -1, -1, -1, -1, -1,
    3, 6, 10, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1,
    0, 10, 8, 0, 5, 10, 0, 1, 5, 5, 6, 10, -1, -1, -1,
    6, 10, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1,
    1, 2, 11, 9, 5, 10, 9, 10, 8, 10, 5, 6, -1, -1, -1,
    0, 10, 3, 0, 6, 10, 0, 9, 6, 5, 6, 9, 1, 2, 11,
    10, 8, 5, 10, 5, 6, 8, 0, 5, 11, 5, 2, 0, 2, 5,
    6, 10, 3, 6, 3, 5, 2, 11, 3, 11, 5, 3, -1, -1, -1,
    5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1,
    9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1,
    1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8,
    1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1, 3, 6, 1, 6, 11, 3, 8, 6, 5, 6, 9, 8, 9, 6,
    11, 1, 0, 11, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1,
    0, 3, 8, 5, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    11, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    10, 5, 11, 7, 5, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    10, 5, 11, 10, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1,
    5, 10, 7, 5, 11, 10, 1, 9, 0, -1, -1, -1, -1, -1, -1,
    11, 7, 5, 11, 10, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1,
    10, 1, 2, 10, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1,
    0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 10, -1, -1, -1,
    9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 10, 7, -1, -1, -1,
    7, 5, 2, 7, 2, 10, 5, 9, 2, 3, 2, 8, 9, 8, 2,
    2, 5, 11, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1,
    8, 2, 0, 8, 5, 2, 8, 7, 5, 11, 2, 5, -1, -1, -1,
    9, 0, 1, 5, 11, 3, 5, 3, 7, 3, 11, 2, -1, -1, -1,
    9, 8, 2, 9, 2, 1, 8, 7, 2, 11, 2, 5, 7, 5, 2,
    1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1,
    9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1,
    9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    5, 8, 4, 5, 11, 8, 11, 10, 8, -1, -1, -1, -1, -1, -1,
    5, 0, 4, 5, 10, 0, 5, 11, 10, 10, 3, 0, -1, -1, -1,
    0, 1, 9, 8, 4, 11, 8, 11, 10, 11, 4, 5, -1, -1, -1,
    11, 10, 4, 11, 4, 5, 10, 3, 4, 9, 4, 1, 3, 1, 4,
    2, 5, 1, 2, 8, 5, 2, 10, 8, 4, 5, 8, -1, -1, -1,
    0, 4, 10, 0, 10, 3, 4, 5, 10, 2, 10, 1, 5, 1, 10,
    0, 2, 5, 0, 5, 9, 2, 10, 5, 4, 5, 8, 10, 8, 5,
    9, 4, 5, 2, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    2, 5, 11, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1,
    5, 11, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1,
    3, 11, 2, 3, 5, 11, 3, 8, 5, 4, 5, 8, 0, 1, 9,
    5, 11, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1,
    8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1,
    0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1,
    9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4, 10, 7, 4, 9, 10, 9, 11, 10, -1, -1, -1, -1, -1, -1,
    0, 8, 3, 4, 9, 7, 9, 10, 7, 9, 11, 10, -1, -1, -1,
    1, 11, 10, 1, 10, 4, 1, 4, 0, 7, 4, 10, -1, -1, -1,
    3, 1, 4, 3, 4, 8, 1, 11, 4, 7, 4, 10, 11, 10, 4,
    4, 10, 7, 9, 10, 4, 9, 2, 10, 9, 1, 2, -1, -1, -1,
    9, 7, 4, 9, 10, 7, 9, 1, 10, 2, 10, 1, 0, 8, 3,
    10, 7, 4, 10, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1,
    10, 7, 4, 10, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1,
    2, 9, 11, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1,
    9, 11, 7, 9, 7, 4, 11, 2, 7, 8, 7, 0, 2, 0, 7,
    3, 7, 11, 3, 11, 2, 7, 4, 11, 1, 11, 0, 4, 0, 11,
    1, 11, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1,
    4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1,
    4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    9, 11, 8, 11, 10, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    3, 0, 9, 3, 9, 10, 10, 9, 11, -1, -1, -1, -1, -1, -1,
    0, 1, 11, 0, 11, 8, 8, 11, 10, -1, -1, -1, -1, -1, -1,
    3, 1, 11, 10, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1, 2, 10, 1, 10, 9, 9, 10, 8, -1, -1, -1, -1, -1, -1,
    3, 0, 9, 3, 9, 10, 1, 2, 9, 2, 10, 9, -1, -1, -1,
    0, 2, 10, 8, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    3, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    2, 3, 8, 2, 8, 11, 11, 8, 9, -1, -1, -1, -1, -1, -1,
    9, 11, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    2, 3, 8, 2, 8, 11, 0, 1, 8, 1, 11, 8, -1, -1, -1,
    1, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
}


// mcube
	// vertices
	// edges



